/*********************************************************************\
*
*                  (c) lkc
*                  All Rights Reserved. lkc Confidential
*
\*********************************************************************/
/*********************************************************************\
*   Title                      :
*
*   Module Description         :
*
*   Author                     : lkc
*
*   Created                    : 2019-3-6
*
\*********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include "SpiUserspace.h"


static void pabort(const char *s)
{
    perror(s);
    abort();
}

int SpiSetOpt(int fd, uint8_t bits,uint32_t speed,uint32_t mode)
{
    //spi mode
    int ret = ioctl(fd, SPI_IOC_WR_MODE32, &mode);
    if (ret == -1)
    {
        pabort("can't set spi mode");
        return ret;
    }

    ret = ioctl(fd, SPI_IOC_RD_MODE32, &mode);
    if (ret == -1)
    {
        pabort("can't get spi mode");
        return ret;
    }

    //bits per word
    ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
    if (ret == -1)
    {
        pabort("can't set bits per word");
        return ret;
    }

    ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
    if (ret == -1)
    {
        pabort("can't get bits per word");
        return ret;
    }

    //max speed hz
    ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
    if (ret == -1)
    {
        pabort("can't set max speed hz");
        return ret;
    }

    ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
    if (ret == -1)
    {
        pabort("can't get max speed hz");
        return ret;
    }

    printf("spi mode: 0x%x\n", mode);
    printf("bits per word: %d\n", bits);
    printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
    return 1;
}

int SpiRead(int fd,uint8_t *readBuf, size_t bufLen, uint16_t delay, uint32_t speed,uint8_t bits,uint32_t mode)
{
    struct spi_ioc_transfer tr = {};//为什么必须要先初始化一下呢
    tr.rx_buf= (unsigned long)readBuf;
    tr.len = bufLen;
    tr.delay_usecs = delay;
    tr.speed_hz = speed;
    tr.bits_per_word = bits;

    if (mode & SPI_TX_QUAD)
        tr.tx_nbits = 4;
    else if (mode & SPI_TX_DUAL)
        tr.tx_nbits = 2;
    if (mode & SPI_RX_QUAD)
        tr.rx_nbits = 4;
    else if (mode & SPI_RX_DUAL)
        tr.rx_nbits = 2;
    if (!(mode & SPI_LOOP)) {
        if (mode & (SPI_TX_QUAD | SPI_TX_DUAL))
            tr.rx_buf = 0;
        else if (mode & (SPI_RX_QUAD | SPI_RX_DUAL))
            tr.tx_buf = 0;
    }
    int ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
    if (ret < 1)
    {
        pabort("can't send spi message");
        return ret;
    }
//    for(size_t i=0;i<bufLen;i++)
//    {
//        printf("%02X ", readBuf[i]);
//    }
//    printf("\n");
    return 1;
}

/********************************************************************\
 *
 * REVISION RECORDS
 *
\*********************************************************************/
/*********************************************************************/
/*
 *
 *
 *
\*********************************************************************/
/*------------------------------The End------------------------------*/
